package com.tpsix.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tpsix.controller.vm.RoleGrantVM;
import com.tpsix.controller.vm.RoleVM;
import com.tpsix.domain.SysMenu;
import com.tpsix.domain.SysRole;
import com.tpsix.domain.SysRoleMenu;
import com.tpsix.service.SysMenuService;
import com.tpsix.service.SysRoleMenuService;
import com.tpsix.service.SysRoleService;
import com.tpsix.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(value = "roles", tags = "系统角色资源")
@RestController
@AllArgsConstructor
@RequestMapping("roles")
public class SysRoleResource {

    private final SysRoleService sysRoleService;

    private final SysMenuService sysMenuService;

    private final SysRoleMenuService sysRoleMenuService;

    @GetMapping
    @ApiOperation("角色列表")
    @PreAuthorize("hasAuthority('sys:role:view')")
    public R<List<SysRole>> roles() {
        return R.ok(sysRoleService.list());
    }

    @GetMapping("page")
    @ApiOperation("角色分页列表")
    @PreAuthorize("hasAuthority('sys:role:view')")
    public R<Page<SysRole>> rolesPage(Page<SysRole> page) {
        Page<SysRole> pages = sysRoleService.page(page);
        return R.ok(pages);
    }

    @PostMapping
    @ApiOperation("新增角色")
    @PreAuthorize("hasAuthority('sys:role:add')")
    public R<Void> add(@RequestBody RoleVM roleVM) {

        int exists = sysRoleService.count(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, roleVM.getRoleCode()));

        if (exists > 0) {
            return R.error("角色标识已存在, 请重新输入");
        }

        return sysRoleService.addOrUpdate(roleVM) ? R.ok() : R.error("添加失败");
    }

    @PutMapping
    @ApiOperation("修改角色")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public R<Void> put(@RequestBody RoleVM roleVM) {
        return sysRoleService.addOrUpdate(roleVM) ? R.ok() : R.error("修改失败");
    }

    @ApiOperation("删除角色")
    @DeleteMapping("{id:\\d+}")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public R<Void> delete(@PathVariable int id) {
        return sysRoleService.removeById(id) ? R.ok() : R.error("删除失败");
    }

    @ApiOperation("批量删除角色")
    @DeleteMapping("/batch-delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public R<Void> batchDelete(@RequestBody List<Integer> id) {
        return sysRoleService.removeByIds(id) ? R.ok() : R.error("删除失败") ;
    }

    /**
     * 角色菜单列表
     */
    @ApiOperation("角色菜单列表")
    @GetMapping("menus/{roleId:\\d+}")
    @PreAuthorize("hasAuthority('sys:role:view')")
    public R roleMenus(@PathVariable int roleId) {
        // 所有菜单
        List<SysMenu> menuTrees = sysMenuService.menuTree(0);

        // 角色菜单 id 列表
        List<SysRoleMenu> roleMenus = sysRoleMenuService
                .lambdaQuery()
                .select(SysRoleMenu::getMenuId)
                .eq(SysRoleMenu::getRoleId, roleId)
                .list();

        List<Long> roleMenuIds = roleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());

        Map<String, Object> results = new HashMap<>(2);
        results.put("allTrees", menuTrees);
        results.put("roleMenuIds", roleMenuIds);

        return R.ok(results);
    }

    /**
     * 授权
     */
    @ApiOperation("授权")
    @PutMapping("granted")
    @PreAuthorize("hasAuthority('sys:role:granted')")
    public R<Void> granted(@RequestBody RoleGrantVM roleGrantVM) {

        List<SysRoleMenu> roleMenus = new ArrayList<>();

        long roleId = roleGrantVM.getRoleId();

        List<Integer> menuIds = roleGrantVM.getMenuIds();

        // 删除全部权限
        sysRoleMenuService.remove(Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getRoleId, roleId));

        if (CollUtil.isNotEmpty(menuIds)) {
            for (Integer menuId : roleGrantVM.getMenuIds()) {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(Long.valueOf(menuId));
                roleMenus.add(roleMenu);
            }
            sysRoleMenuService.saveBatch(roleMenus);
        }
        return R.ok();
    }


}
